package _05_matrix;

public class Matrix {
    
    // 矩阵行数、列数
    private int rows, columns;
    // 二维数组，存储矩阵元素
    private int[][] element;
    // 常量，指定element数组容量的最小值
    private static final int MIN_CAPACITY = 6;
    
    // 构造mxn矩阵，元素为0
    public Matrix(int m, int n) {
        if (m >= 0 && n >= 0) {
            this.rows = m;
            this.columns = n;
            // 如果小于容量最小值
            if (m < MIN_CAPACITY) {
                m = MIN_CAPACITY;
            }
            if (n < MIN_CAPACITY) {
                n = MIN_CAPACITY;
            }
            this.element = new int[m][n];
        } else {
            throw new IllegalArgumentException("矩阵行列数不能小于0，m = " + m + "，n = " + n);
        }
    }
    
    // 构造nxn矩阵，元素为0
    public Matrix(int n) {
        this(n, n);
    }
    
    // 构造0x0矩阵，存储容量为最小值
    public Matrix() {
        this(0, 0);
    }
    
    // 构造mxn矩阵，有values[][]提供元素
    public Matrix(int m, int n, int[][] values) {
        this(m, n);
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                this.element[i][j] = values[i][j];
            }
        }
    }
    
    public int getRows() {
        return rows;
    }

    public int getColumns() {
        return columns;
    }
    
    // 返回第i行第j列元素。若i、j序号越界，则抛出序号越界异常
    public int get(int i, int j) {
        if (i >= 0 && i < this.rows && j < this.columns) {
            return this.element[i][j];
        } else {
            throw new IndexOutOfBoundsException("i = " + i + "，j = " + j);
        }
    }
    
    // 返回矩阵元素描述字符串，行主序遍历
    public String toString() {
        String str = "矩阵" + this.getClass().getName() + " (" + this.rows + "x" + this.columns + "):\n";
        for (int i = 0; i < this.rows; i++) {
            for (int j = 0; j < this.columns; j++) {
                // "%6"格式表示十进制整数占6位
                str += String.format("%6d", this.element[i][j]);
            }
            str += "\n";
        }
        return str;
    }
    
    // 返回第i行第j列元素为x
    public void set(int i, int j, int x) {
        if (i >= 0 && i < this.rows && j >= 0 && j < this.columns) {
            this.element[i][j] = x;
        } else {
            throw new IndexOutOfBoundsException("i = " + i + "，j = " + j);
        }
    }
    
    // 设置矩阵为m行n列。若参数指定行列数较大，则将矩阵扩容，并复制原矩阵元素
    public void setRowsColumns(int m, int n) {
        if (m > 0 && n > 0) {
            // 参数指定的行数或列数较大时，扩充二维数组容量
            if (m > this.rows || n > this.columns) {
                int[][] temp = this.element;
                this.element = new int[m * 2][n * 2];
                for (int i = 0; i < this.rows; i++) {
                    for (int j = 0; j < this.columns; j++) {
                        this.element[i][j] = temp[i][j];
                    }
                }
            }
            this.rows = m;
            this.columns = n;
        } else {
            throw new IllegalArgumentException("矩阵行列数不能<0，m = " + m + "，n = " + n);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[][] arr2d0 = {{1, 2, 3}, {4, 5, 6, 7}};
        Matrix m0 = new Matrix(3, 4, arr2d0);
        System.out.println(m0);
        m0.set(2, 2, 1234567);
        m0.set(2, 3, 1234567);
        System.out.println(m0);
        int[][] arr2d1 = {{1,2,3}, {1, 2, 3, 4, 5, 6, 7, 8, 9}, {4, 5, 6, 7}};
        Matrix m1 = new Matrix(6, 9, arr2d1);
        System.out.println(m1);
        m1.setRowsColumns(2, 4);
        System.out.println(m1);
        m1.setRowsColumns(7, 3);
        System.out.println(m1);
    }

}
